<template>
  <div class="ai-container">
    <!-- 左侧选择面板 -->
    <div class="selection-panel">
      <div class="panel-section">
        <h3>选择社团</h3>
        <select 
          v-model="selectedClubId" 
          @change="onClubChange" 
          class="select-input"
          :disabled="loadingClubs"
        >
          <option value="">请选择社团</option>
          <option v-for="club in clubs" :key="club.id" :value="club.id">
            {{ club.name }}
          </option>
        </select>
        <div v-if="loadingClubs" class="loading-text">加载中...</div>
      </div>

      <div class="panel-section">
        <h3>选择活动</h3>
        <select 
          v-model="selectedActivityId" 
          :disabled="!selectedClubId || loadingActivities" 
          class="select-input"
        >
          <option value="">请选择活动</option>
          <option v-for="activity in activities" :key="activity.id" :value="activity.id">
            {{ activity.title }}
          </option>
        </select>
        <div v-if="loadingActivities" class="loading-text">加载中...</div>
        <div v-else-if="selectedClubId && activities.length === 0" class="empty-text">
          该社团暂无活动
        </div>
      </div>

      <div class="panel-section">
        <h3>自定义要求（可选）</h3>
        <textarea 
          v-model="customPrompt" 
          placeholder="例如：重点突出活动中的创新点、需要改进的地方等..."
          class="textarea-input"
          rows="3"
        ></textarea>
      </div>

      <button 
        @click="generateSummary" 
        :disabled="!canGenerate"
        class="generate-btn"
      >
        {{ isLoading ? '生成中...' : '智能生成活动总结' }}
      </button>

      <!-- 选中的活动信息预览 -->
      <div v-if="selectedActivity" class="activity-preview">
        <h4>活动信息预览</h4>
        <div class="preview-content">
          <p><strong>标题：</strong>{{ selectedActivity.title }}</p>
          <p v-if="selectedActivity.description">
            <strong>描述：</strong>{{ selectedActivity.description }}
          </p>
          <p v-if="selectedActivity.schedule">
            <strong>时间：</strong>{{ formatDate(selectedActivity.schedule) }}
          </p>
          <p v-if="selectedActivity.location">
            <strong>地点：</strong>{{ selectedActivity.location }}
          </p>
        </div>
      </div>
    </div>

    <!-- 右侧结果展示 -->
    <div class="result-panel">
      <div class="result-header">
        <h3>活动总结</h3>
        <div class="action-buttons">
          <button @click="copyResult" class="action-btn" :disabled="!summaryContent || isLoading">
            <span class="btn-icon">📋</span> 复制
          </button>
          <button @click="exportResult" class="action-btn" :disabled="!summaryContent || isLoading">
            <span class="btn-icon">📄</span> 导出
          </button>
          <button @click="stopGenerate" class="action-btn stop-btn" :disabled="!isLoading">
            <span class="btn-icon">⏹️</span> 停止
          </button>
          <button @click="clearResult" class="action-btn" :disabled="(!summaryContent && !isLoading) || isLoading">
            <span class="btn-icon">🗑️</span> 清空
          </button>
        </div>
      </div>
      
      <div class="summary-content" ref="summaryBox">
        <div v-if="isLoading && !summaryContent" class="loading-indicator">
          <div class="loading-dots">
            <span></span>
            <span></span>
            <span></span>
          </div>
          <div>AI正在分析活动数据并生成总结...</div>
        </div>
        
        <!-- 关键修改：实时显示文字内容 -->
        <div v-if="summaryContent" class="summary-text">
          <div class="content-text">{{ summaryContent }}</div>
          <div v-if="isLoading" class="streaming-cursor">▊</div>
        </div>
        
        <div v-else-if="!isLoading" class="empty-state">
          <div class="empty-icon">📝</div>
          <div class="empty-title">智能活动总结生成器</div>
          <div class="empty-desc">选择社团和活动，AI将为您生成专业的活动总结报告</div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, watch, nextTick } from "vue"
import { 
  getClubList, 
  getActivitiesByClubId, 
  getActivityDetail,
  streamActivitySummary 
} from '@/api/aiSummary'

// 响应式数据
const selectedClubId = ref("")
const selectedActivityId = ref("")
const customPrompt = ref("")
const clubs = ref([])
const activities = ref([])
const selectedActivity = ref(null)
const summaryContent = ref("")
const isLoading = ref(false)
const loadingClubs = ref(false)
const loadingActivities = ref(false)
const summaryBox = ref(null)
let source = null
let timeoutId = null

// 计算属性
const canGenerate = computed(() => {
  return selectedClubId.value && selectedActivityId.value && !isLoading.value
})

// 监听活动ID变化，加载活动详情
watch(selectedActivityId, async (newId) => {
  if (newId) {
    try {
      const response = await getActivityDetail(newId)
      if (response.code === 200) {
        selectedActivity.value = response.data
      } else {
        console.error("加载活动详情失败:", response.message)
        selectedActivity.value = null
      }
    } catch (error) {
      console.error("加载活动详情失败:", error)
      selectedActivity.value = null
    }
  } else {
    selectedActivity.value = null
  }
})

// 生命周期
onMounted(() => {
  loadClubs()
})

onUnmounted(() => {
  closeStream()
  clearTimeout(timeoutId)
})

// 关闭流式连接
const closeStream = () => {
  if (source) {
    source.close()
    source = null
    console.log("🔒 SSE连接已关闭")
  }
}

// 停止生成
const stopGenerate = () => {
  console.log("⏹️ 用户停止生成")
  closeStream()
  clearTimeout(timeoutId)
  isLoading.value = false
}

// 加载社团列表
const loadClubs = async () => {
  loadingClubs.value = true
  try {
    const response = await getClubList({ page: 1, size: 100 })
    if (response.code === 200) {
      clubs.value = response.data.records || response.data.list || response.data
      console.log(`✅ 加载社团列表成功，共 ${clubs.value.length} 个社团`)
    } else {
      console.error("加载社团列表失败:", response.message)
    }
  } catch (error) {
    console.error("加载社团列表失败:", error)
  } finally {
    loadingClubs.value = false
  }
}

// 社团改变时加载活动
const onClubChange = async () => {
  selectedActivityId.value = ""
  selectedActivity.value = null
  activities.value = []
  summaryContent.value = ""
  closeStream()
  
  if (!selectedClubId.value) return
  
  loadingActivities.value = true
  try {
    const response = await getActivitiesByClubId(selectedClubId.value)
    if (response.code === 200) {
      activities.value = response.data
      console.log(`✅ 加载活动列表成功，共 ${activities.value.length} 个活动`)
    } else {
      console.error("加载活动列表失败:", response.message)
    }
  } catch (error) {
    console.error("加载活动列表失败:", error)
  } finally {
    loadingActivities.value = false
  }
}

// 生成活动总结 - 核心修复
const generateSummary = () => {
  if (!canGenerate.value) return
  
  // 关闭之前的连接
  closeStream()
  clearTimeout(timeoutId)
  
  isLoading.value = true
  summaryContent.value = "" // 清空之前的内容
  
  // 构建请求参数
  const params = {
    clubId: selectedClubId.value,
    activityId: selectedActivityId.value
  }
  
  if (customPrompt.value.trim()) {
    params.customPrompt = customPrompt.value.trim()
  }
  
  console.log("🚀 开始生成活动总结，参数:", params)
  
  try {
    // 创建EventSource连接
    source = streamActivitySummary(params)
    
    source.onopen = (event) => {
      console.log("🔗 SSE连接已建立", event)
    }
    
    source.onmessage = (event) => {
      const data = event.data
      
      if (data === "[DONE]") {
        console.log("✅ 活动总结生成完成")
        isLoading.value = false
        closeStream()
        clearTimeout(timeoutId)
        return
      }
      
      if (data.startsWith("[ERROR]")) {
        console.error("❌ 生成失败:", data)
        summaryContent.value += `\n\n【生成错误】${data.substring(7)}`
        isLoading.value = false
        closeStream()
        clearTimeout(timeoutId)
        return
      }
      
      // 关键修复：实时更新并显示文字内容
      if (data && data.trim() !== '') {
        summaryContent.value += data
        
        // 立即更新DOM并滚动到底部
        nextTick(() => {
          if (summaryBox.value) {
            summaryBox.value.scrollTop = summaryBox.value.scrollHeight
          }
        })
      }
    }
    
    source.onerror = (event) => {
      console.error("🔌 SSE连接错误", event)
      if (!summaryContent.value) {
        summaryContent.value = "生成失败，请检查网络连接后重试"
      }
      isLoading.value = false
      closeStream()
      clearTimeout(timeoutId)
    }
    
    // 添加超时处理
    timeoutId = setTimeout(() => {
      if (isLoading.value && summaryContent.value === "") {
        console.warn("⏰ 请求超时")
        summaryContent.value = "请求超时，请检查网络连接后重试"
        isLoading.value = false
        closeStream()
      }
    }, 60000) // 60秒超时
    
  } catch (error) {
    console.error("🚨 创建SSE连接失败:", error)
    summaryContent.value = "创建连接失败: " + error.message
    isLoading.value = false
  }
}

// 复制结果
const copyResult = async () => {
  if (!summaryContent.value) return
  
  try {
    await navigator.clipboard.writeText(summaryContent.value)
    alert("✅ 活动总结已复制到剪贴板")
  } catch (error) {
    console.error("复制失败:", error)
    // 降级方案
    const textarea = document.createElement('textarea')
    textarea.value = summaryContent.value
    document.body.appendChild(textarea)
    textarea.select()
    document.execCommand('copy')
    document.body.removeChild(textarea)
    alert("✅ 活动总结已复制到剪贴板")
  }
}

// 导出结果
const exportResult = () => {
  if (!summaryContent.value) return
  
  const activityTitle = selectedActivity.value?.title || '未知活动'
  const dateStr = new Date().toISOString().split('T')[0]
  const filename = `活动总结_${activityTitle}_${dateStr}.txt`
  
  // 清理文件名中的非法字符
  const cleanFilename = filename.replace(/[<>:"/\\|?*]/g, '_')
  
  const blob = new Blob([summaryContent.value], { type: 'text/plain;charset=utf-8' })
  const url = URL.createObjectURL(blob)
  const a = document.createElement('a')
  a.href = url
  a.download = cleanFilename
  document.body.appendChild(a)
  a.click()
  document.body.removeChild(a)
  URL.revokeObjectURL(url)
}

// 清空结果
const clearResult = () => {
  if (isLoading.value) {
    if (!confirm("正在生成中，确定要清空吗？")) {
      return
    }
    stopGenerate()
  }
  summaryContent.value = ""
}

// 格式化日期
const formatDate = (dateString) => {
  if (!dateString) return ''
  try {
    const date = new Date(dateString)
    return date.toLocaleString('zh-CN', {
      year: 'numeric',
      month: '2-digit',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit'
    })
  } catch (error) {
    return dateString
  }
}
</script>

<style scoped>
.ai-container {
  display: flex;
  height: 86vh;
  background: #f5f7fa;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

.selection-panel {
  width: 350px;
  background: white;
  padding: 24px;
  border-right: 1px solid #e1e5e9;
  display: flex;
  flex-direction: column;
  gap: 24px;
  overflow-y: auto;
}

.result-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  background: white;
  margin: 20px;
  border-radius: 12px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
}

.panel-section h3 {
  margin: 0 0 12px 0;
  font-size: 14px;
  color: #1f2937;
  font-weight: 600;
}

.select-input, .textarea-input {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid #d1d5db;
  border-radius: 8px;
  font-size: 14px;
  transition: border-color 0.2s;
  box-sizing: border-box;
}

.select-input:focus, .textarea-input:focus {
  outline: none;
  border-color: #3b82f6;
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}

.textarea-input {
  resize: vertical;
  font-family: inherit;
  line-height: 1.5;
  min-height: 80px;
}

.loading-text, .empty-text {
  font-size: 12px;
  color: #6b7280;
  margin-top: 4px;
}

.empty-text {
  color: #ef4444;
}

.generate-btn {
  width: 100%;
  padding: 12px;
  background: linear-gradient(135deg, #3b82f6, #1d4ed8);
  color: white;
  border: none;
  border-radius: 8px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s;
}

.generate-btn:hover:not(:disabled) {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(59, 130, 246, 0.4);
}

.generate-btn:disabled {
  background: #9ca3af;
  transform: none;
  box-shadow: none;
  cursor: not-allowed;
}

.activity-preview {
  border-top: 1px solid #e5e7eb;
  padding-top: 16px;
}

.activity-preview h4 {
  margin: 0 0 12px 0;
  font-size: 14px;
  color: #374151;
}

.preview-content {
  background: #f8fafc;
  padding: 12px;
  border-radius: 6px;
  font-size: 13px;
}

.preview-content p {
  margin: 4px 0;
  line-height: 1.4;
  word-break: break-word;
}

.result-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px 24px;
  border-bottom: 1px solid #e5e7eb;
}

.result-header h3 {
  margin: 0;
  color: #111827;
  font-size: 18px;
  font-weight: 700;
}

.action-buttons {
  display: flex;
  gap: 8px;
}

.action-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  background: white;
  border: 1px solid #d1d5db;
  border-radius: 6px;
  font-size: 12px;
  cursor: pointer;
  transition: all 0.2s;
}

.action-btn:hover:not(:disabled) {
  background: #f3f4f6;
  border-color: #9ca3af;
}

.action-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.stop-btn {
  color: #ef4444;
  border-color: #fecaca;
}

.stop-btn:hover:not(:disabled) {
  background: #fef2f2;
  border-color: #fca5a5;
}

.btn-icon {
  font-size: 14px;
}

.summary-content {
  flex: 1;
  padding: 0;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.loading-indicator {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: #4b5563;
  gap: 16px;
  padding: 40px;
  text-align: center;
}

.loading-dots {
  display: flex;
  gap: 6px;
}

.loading-dots span {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #3b82f6;
  animation: bounce 1.4s infinite ease-in-out;
}

.loading-dots span:nth-child(1) { animation-delay: -0.32s; }
.loading-dots span:nth-child(2) { animation-delay: -0.16s; }

@keyframes bounce {
  0%, 80%, 100% {
    transform: scale(0.8);
    opacity: 0.5;
  }
  40% {
    transform: scale(1);
    opacity: 1;
  }
}

/* 关键样式：内容显示区域 */
.summary-text {
  flex: 1;
  padding: 24px;
  overflow-y: auto;
  position: relative;
}

.content-text {
  white-space: pre-wrap;
  line-height: 1.7;
  font-size: 14px;
  color: #374151;
  word-break: break-word;
  min-height: 200px;
}

/* 流式输入光标效果 */
.streaming-cursor {
  display: inline-block;
  color: #3b82f6;
  font-weight: bold;
  animation: blink 1s infinite;
  margin-left: 2px;
}

@keyframes blink {
  0%, 50% { opacity: 1; }
  51%, 100% { opacity: 0; }
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: #9ca3af;
  text-align: center;
  padding: 40px;
}

.empty-icon {
  font-size: 64px;
  margin-bottom: 16px;
  opacity: 0.7;
}

.empty-title {
  font-size: 18px;
  font-weight: 600;
  margin-bottom: 8px;
  color: #6b7280;
}

.empty-desc {
  font-size: 14px;
  line-height: 1.5;
  max-width: 300px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .ai-container {
    flex-direction: column;
    height: auto;
  }
  
  .selection-panel {
    width: 100%;
    border-right: none;
    border-bottom: 1px solid #e1e5e9;
  }
  
  .result-panel {
    margin: 10px;
  }
  
  .action-buttons {
    flex-wrap: wrap;
  }
}
</style>